package test;

import org.junit.Test;

import java.lang.reflect.InvocationTargetException;

public class test方法中传入一个类 {
    /**
     * 当一个方法参数为接口的时候，应该如何传参呢？
     * 答案：可以传递 类、抽象类、对象。即往下兼容
     *
     * 模拟实验：代码所示
     *
     * 总结： 而对于参数：和数据类型一样都是向下兼容得。
     */
    @Test
    public void test() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        test方法中传入一个类 test = new test方法中传入一个类();
        //1、传入一个匿名内部类的对象
        test.ATestMethod(new AA() {
            @Override
            public void test1() {
                System.out.println("测试方法流弊。。。");
            }

            @Override
            public void test2() {
                System.out.println("测试方法啦啦啦。。。");
            }
        });

        //2、传入一个对象
        test.ATestMethod(new A());
        //3、传入一个对象（通过匿名内部类的方式）
        test.ATestMethod(new B() {});


        //只能往下兼容：通过泛型的方式，只能向下兼容
        test.ATestMethod2(new A());
/*        test.ATestMethod2(new AA(){//通过接口传递一个实现类的对象，肯定报错

            @Override
            public void test1() {
                System.out.println("测试方法一。。。");
            }

            @Override
            public void test2() {
                System.out.println("测试方法一。。。");
            }
        });*/


        //注意这里传递的是一个对象，不是一个类！这里通过匿名内部类的方式来创建一个对象
        test.ATestMethod(new B() {});

        test.ATestMehthod3(A.class);
        test.ATestMehthod4(A.class);

    }

    /**
     * 方法参数为接口时：可以传 （类、对象） 作为参数
     * @param a
     */
    public void ATestMethod(AA a){
        a.test1();
        a.test2();
    }

    /**
     * 当方法参数为类时，能不能传入一个接口或者类呢呢？
     * 不能，就像数据类型一样：只能往下兼容！
     * @param a
     */
    public void ATestMethod2(A a){
        a.test1();
        a.test2();
    }
    //这里才是真正传递一个类（也只是一个类对象，并不是一个真正意义上的类）
    public void ATestMehthod3(Class<A> aaClass) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        A a = aaClass.getDeclaredConstructor().newInstance();//通过类对象来创建一个对象
        a.test1();
        a.test2();
        a.test3();
    }

    //这里才是真正传递一个特定的类（其实也只是一个类对象，并不是一个真正意义上的类）
    public <T> void  ATestMehthod4(Class<T> aaClass) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        A c = (A)aaClass.getDeclaredConstructor().newInstance();//通过类对象来创建一个对象
        c.test1();
//        c.test4();
    }
}


interface AA{
    void test1();
    void test2();
}
class A implements AA{
    @Override
    public void test1() {
        System.out.println("测试方法一。。。");
    }

    @Override
    public void test2() {
        System.out.println("测试方法二。。。");
    }

    public void test3(){
        System.out.println("hello");
    }
}
abstract class B implements  AA{
    @Override
    public void test1() {
        System.out.println("抽象方法一。。。");
    }

    @Override
    public void test2() {
        System.out.println("抽象方法一。。。");
    }
//        public abstract void test3();
}
class C extends A{
    public void test4(){
        System.out.println("类C的test4().....");
    }
}

